package com.hgy.plugin.soap.servlet;

import java.util.Set;

import javax.servlet.ServletConfig;
import javax.servlet.annotation.WebServlet;

import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.transport.servlet.CXFNonSpringServlet;

import com.hgy.common.utils.CollectionUtil;
import com.hgy.common.utils.StringUtil;
import com.hgy.framework.helper.BeanHelper;
import com.hgy.framework.helper.ClassHelper;
import com.hgy.plugin.soap.SoapConstant;
import com.hgy.plugin.soap.annotation.Soap;
import com.hgy.plugin.soap.helper.SoapHelper;

/**
 * SOAP Servlet
 * 处理 /soap/* 请求
 * 
 * @author alone
 *
 */
@WebServlet(urlPatterns=SoapConstant.SERVER_URL, loadOnStartup=0)
public class SoapServlet extends CXFNonSpringServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Override
	protected void loadBus(ServletConfig sc) {
		
		super.loadBus(sc);
		Bus bus = getBus();
		BusFactory.setDefaultBus(bus);
		
		publishedSoapService();
	}

	/**
	 * 发布 SOAP 服务
	 */
	private void publishedSoapService() {
		
		Set<Class<?>> soapClassSet = ClassHelper.getClassSetByAnnotation(Soap.class);
		if(CollectionUtil.isNotEmpty(soapClassSet)){
			for (Class<?> soapClass : soapClassSet) {
				String address = getAddress(soapClass);
				Class<?> soapInterfaceClass = getSoapInterfaceClass(soapClass);
				Object soapInstance = BeanHelper.getBean(soapClass);
				SoapHelper.publishService(address, soapInterfaceClass, soapInstance);
			}
		}
	}

	/**
	 * 获取 发布地址
	 * 
	 * @param soapClass
	 * @return
	 */
	private String getAddress(Class<?> soapClass) {
		String address;
		
		//若 soap 注解 value 不为空 则取当前值, 否则获取类名
		String soapValue = soapClass.getAnnotation(Soap.class).value();
		if(StringUtil.isNotEmpty(soapValue)){
			address = soapValue;
		}else{
			address = getSoapInterfaceClass(soapClass).getSimpleName();
		}
		if(!address.startsWith("/")){
			address = "/" + address;
		}
		address = address.replaceAll("\\/+", "/");
		return address;
	}

	/**
	 * 获取Soap 实现类的第一个接口作为 SOAP 服务接口
	 * 
	 * @param soapClass
	 * @return
	 */
	private Class<?> getSoapInterfaceClass(Class<?> soapClass) {
		return soapClass.getInterfaces()[0];
	}
}
